package com.xcc.netty.socket.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;

/**
 * @author frosty
 * @description
 * @date 2019-12-30 30:16:10
 */


public class MyFileChannel {

    public static void main(String[] args) throws  Exception{
        mappedByteBuffer();
    }


    /**
     *  利用channel  buffer  写入文件
     * @throws Exception
     */
    public  static  void buffWrite() throws  Exception{

        String s="hello world 我";
        //创建输出流 ->channel
        FileOutputStream fos=new FileOutputStream("/home/swst/channel.txt",true);  //追加
        //通过输出流得到channel
        FileChannel channel = fos.getChannel();
        //创建一个bytebuff
        ByteBuffer buff=ByteBuffer.allocate(1024);
        //将string 放入buffer中
        buff.put(s.getBytes("utf8"));
        //翻转buffer
        buff.flip();
        channel.write(buff);
        fos.close();
    }

    /**
     * buff 读取文件
     * @throws Exception
     */

    public static  void buffRead() throws  Exception{
        FileInputStream fis=new FileInputStream("/home/swst/channel.txt");
        FileChannel channel = fis.getChannel();
        ByteBuffer byteBuffer=ByteBuffer.allocate(10);
        int read=0;
        while ((read = channel.read(byteBuffer))!=-1){
            byteBuffer.flip();
            System.out.println(byteBuffer.array().length);
            System.out.println(new String(byteBuffer.array(),0,byteBuffer.limit()));

        }
            fis.close();


    }


    /**
     * 使用buffer 拷贝文件
     * @throws Exception
     */

    public  static  void copyFile() throws Exception{
        FileInputStream fis=new FileInputStream("/home/swst/channel.txt");
        FileOutputStream fos=new FileOutputStream("/home/swst/cha2.txt",true);

         FileChannel fischannel = fis.getChannel();
         FileChannel fosChannel = fos.getChannel();
         ByteBuffer buffer=ByteBuffer.allocate(10);
         int len=0;
          while (true){


           len=fischannel.read(buffer);
              System.out.println(len);
          if(len==-1){
              break;
          }
             buffer.flip();
              fosChannel.write(buffer);
              //这一步必须有  不然程序无法停止  读不到结束位置
              buffer.clear();
          }
          
         fis.close();
          fos.close();



    }

    /**
     * 直接使用fileChannel transferForm  拷贝文件
     */
    public  static void copyFileByTransferForm() throws  Exception
    {
        FileInputStream fis=new FileInputStream("/home/swst/channel.txt");
        FileOutputStream fos=new FileOutputStream("/home/swst/chatransfer.txt",true);
         FileChannel fisChannel = fis.getChannel();
         FileChannel foschannel = fos.getChannel();
         foschannel.transferFrom(fisChannel,0,fisChannel.size());
         fis.close();
         fos.close();

    }


    /**
     *MappendByteBuffer  直接在内存中修改文件  操作系统不需要再考一遍文件
     */
    public  static void  mappedByteBuffer() throws  Exception{
         //rw  是指  可读可写
         RandomAccessFile raf = new RandomAccessFile("/home/swst/channel.txt","rw");
        //得到通道
         FileChannel channel = raf.getChannel();
        /**
         *  参数一 FIleChannel.MODE read_WRITE  使用读写模式
          *  参数二  修改的起始位置
         *   参数三   修改的最大个数  从起始位置开始算  下面是  0 开始  最多五个  0-4
          */
         MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
      //进行文件修改操作
        System.out.println('我'+1);
         map.put("我2".getBytes("utf8"));
     //   map.put(0,(byte) 'y');
         raf.close();

    }


    /**
     * 分散和聚合
     * Scatering  将数据写入到buffer时  可以采用buffer 数组  依次写入[分散]
     * Gathering  从buffer读取数据时 可以采用buffer数组  依次读取
     */
    public  static  void scatteringGathering ()throws Exception{
         //使用 ServerSocketChannel    SocketChannel

        ServerSocketChannel ssc= ServerSocketChannel.open();


    }
}
